import { Controller } from 'egg';
const Sequelize = require('sequelize');
const Op = Sequelize.Op;
// const consola = require('consola');
require('colors');

export default class LabelController extends Controller {

  /**
   * @api {get} category/fontList 获取一级分类列表(前台)
   *  
   * @apiName fontList
   * @apiGroup Category
   * @apiParam {String} categoryType 资源分类类型
   * @apiParam {String} [pageSize] 页数
   * @apiParam {String} [pageNo] 页码
   * @apiDescription 获取一级分类列表 不填写pageSize或者pageNo表示获取全部
   *
   */
  public async fontList(ctx) {
    let { categoryType, pageSize, pageNo } = ctx.request.query;
    let searchOptions = {
      attributes: {
        exclude: ['id', 'createdAt', 'updatedAt'],
      }
    };
    if (pageSize && pageNo) {
      let pageInfo = this.ctx.helper.changePage(pageNo, pageSize);
      searchOptions = Object.assign(searchOptions, {
        limit: pageInfo.limit,
        offset: pageInfo.offset
      });
    }
    if (categoryType !== '') {
      if (searchOptions.hasOwnProperty('where')) {
        const where = 'where';
        searchOptions[where].categoryType = categoryType;
      } else {
        searchOptions = Object.assign(searchOptions, {
          where: {
            categoryType: categoryType
          },
        });
      }
    }
    const where = 'where';
    searchOptions[where].isShow = true;
    let result = await this.ctx.model.Category.findAndCountAll(searchOptions);
    ctx.response.body = {
      code: 200,
      data: result.rows,
      count: result.count,
      status: '成功'
    }
  }

  /**
   * @api {get} category/fontSubList 获取二级分类列表(前台)
   *  
   * @apiName fontSubList
   * @apiGroup Category
   * @apiParam {ArrayString} fatherIds 父节点ID
   * @apiParam {String} [categoryType] 资源分类类型
   * @apiParam {Number} [pageSize] 页容量
   * @apiParam {Number} [pageNo] 页码
   * @apiDescription 获取二级级分类列表
   *
   */
  public async fontSubList() {
    let { fatherIds, categoryType = '', pageSize, pageNo } = this.ctx.request.query;
    try {
      let searchObject = {};
      let whereObject = {};

      if (pageSize && pageNo) {
        let pageInfo = this.ctx.helper.changePage(pageNo, pageSize);
        searchObject = Object.assign(searchObject, {
          limit: pageInfo.limit,
          offset: pageInfo.offset
        });
      }

      if (fatherIds && fatherIds.length !== 0) {
        let mapFatherArray = fatherIds.split(',');
        let newFatherArray = mapFatherArray.map(item => {
          return parseInt(item);
        });
        whereObject = {
          fatherId: {
            [Op.or]: newFatherArray
          }
        };

      }
      if (categoryType !== '') {
        if (whereObject.hasOwnProperty('fatherId')) {
          const showLabelType = 'labelType';
          whereObject[showLabelType] = categoryType;
        } else {
          whereObject = {
            categoryType: categoryType
          };
        }
      }
      searchObject = Object.assign(searchObject, {
        attributes: {
          exclude: ['id', 'createdAt', 'updatedAt'],
        },
        where: whereObject
      });
      const where = 'where';
      searchObject[where].isShow = true;
      let result = await this.ctx.model.SubLabel.findAndCountAll(searchObject);
      this.ctx.response.body = {
        code: 200,
        data: result.rows,
        count: result.count,
        status: '成功'
      };
    } catch (msg) {
      this.ctx.response.body = msg;
    }
  }

  /**
   * @api {get} category/list 获取一级分类列表(后台)
   *  
   * @apiName list
   * @apiGroup Category
   * @apiParam {String} [labelName] 模糊匹配的分类名
   * @apiParam {String} [pageSize] 页数
   * @apiParam {String} [pageNo] 页码
   * @apiParam {String} categoryType 资源分类类型
   * @apiHeaderExample {json} headers:
   *     {
   *       "token": "admin_token"
   *     }
   * @apiDescription 获取一级分类列表 不填写pageSize或者pageNo表示获取全部
   * 
   */
  public async list() {
    let { labelName, categoryType = '' } = this.ctx.request.query;
    let searchOptions = {
      attributes: {
        exclude: ['id', 'createdAt', 'updatedAt'],
      }
    };
    if (labelName) {
      searchOptions = Object.assign(searchOptions, {
        where: {
          theme: {
            [Op.like]: `%${labelName}%`
          }
        },
      });
    }

    if (categoryType !== '') {
      if (searchOptions.hasOwnProperty('where')) {
        const where = 'where';
        searchOptions[where].categoryType = categoryType;
      } else {
        searchOptions = Object.assign(searchOptions, {
          where: {
            categoryType: categoryType
          },
        });
      }
    }
    let result = await this.ctx.model.Category.findAndCountAll(searchOptions);
    this.ctx.response.body = {
      code: 200,
      data: result.rows,
      count: result.count,
      status: '成功'
    }
  }

  /**
   * @api {get} category/subList 获取二级分类列表(后台)
   *  
   * @apiName subList
   * @apiGroup Category
   * @apiParam {ArrayString} fatherIds 父节点ID
   * @apiParam {Number} [pageSize] 页容量
   * @apiParam {Number} [pageNo] 页码
   * @apiHeaderExample {json} headers:
   *     {
   *       "token": "admin_token"
   *     }
   * @apiDescription 获取二级级分类列表
   *
   */
  public async subList() {
    let { fatherIds, pageSize, pageNo } = this.ctx.request.query;
    try {
      let searchObject = {};
      let whereObject = {};

      if (pageSize && pageNo) {
        let pageInfo = this.ctx.helper.changePage(pageNo, pageSize);
        searchObject = Object.assign(searchObject, {
          limit: pageInfo.limit,
          offset: pageInfo.offset
        });
      }

      if (fatherIds && fatherIds.length !== 0) {
        let mapFatherArray = fatherIds.split(',');
        let newFatherArray = mapFatherArray.map(item => {
          return parseInt(item);
        });
        whereObject = {
          fatherId: {
            [Op.or]: newFatherArray
          }
        };

      }

      searchObject = Object.assign(searchObject, {
        attributes: {
          exclude: ['id', 'createdAt', 'updatedAt'],
        },
        where: whereObject
      });
      let result = await this.ctx.model.SubCategory.findAndCountAll(searchObject);
      this.ctx.response.body = {
        code: 200,
        data: result.rows,
        count: result.count,
        status: '成功'
      };
    } catch (msg) {
      this.ctx.response.body = msg;
    }
  }

  /**
   * @api {post} category/show 分类是否显示
   *  
   * @apiName show
   * @apiGroup Category
   * @apiParam {String} type 分类类型[1-一级分类 2-二级分类]
   * @apiParam {Boolean} status 分类状态[true-显示，false-隐藏]
   * @apiParam {String} fatherId 父分类id
   * @apiParam {String} categoryId 分类id
   * @apiHeaderExample {json} headers:
   *     {
   *       "token": "admin_token"
   *     }
   *
   * @apiDescription 只要在type=2 是需要传入fatherId
   *
   */

  public async show(ctx) {
    let {
      type,
      categoryId,
      subCategoryId,
      status,
      fatherId
    } = ctx.request.body;
    try {
      let whatType = ctx.helper.whatType;

      if (!Object.is(await whatType(parseInt(type)), 'Number') || !Object.is(await whatType(parseInt(categoryId)), 'Number')) {
        throw ctx.helper.getErrorMsg(207);
      }
      switch (parseInt(type)) {
        case 2:
          await this.ctx.model.SubCategory.update(
            {
              isShow: status
            },
            {
              where: {
                fatherId: parseInt(fatherId),
                subCategoryId: parseInt(subCategoryId)
              }
            });
          break;
        default:
        case 1:
          await this.ctx.model.Category.update(
            {
              isShow: status
            },
            {
              where: {
                categoryId: parseInt(categoryId)
              }
            });
          break;
      }
      ctx.response.body = {
        code: 200,
        status: '修改成功'
      };
    } catch (error_info) {
      ctx.response.body = error_info;
    }
  }

  /**
   * @api {post} category/add 添加分类
   *  
   * @apiName add
   * @apiGroup Category
   * @apiParam {String} type 分类类型[1-一级分类 2-二级分类]
   * @apiParam {String} name 分类名称
   * @apiParam {String} fatherId 父分类id
   * @apiHeaderExample {json} headers:
   *     {
   *       "token": "admin_token"
   *     }
   *
   * @apiDescription 只要在type=2 是需要传入fatherId
   *
   */
  public async add() {
    try {
      let { type, fatherId, name } = this.ctx.request.body;
      let tempTypeOne = [];
      let tempTypeTwo = [];
      if (!type || (parseInt(type) !== 1 && parseInt(type) !== 2)) {
        throw this.ctx.helper.getErrorMsg(207);
      }
      if (parseInt(type) === 2 && !fatherId) {
        throw this.ctx.helper.getErrorMsg(207);
      }
      if (parseInt(type) === 2 && fatherId) {

        // 新写入的分类是否已经存在
        let subData = await this.ctx.model.SubCategory.findAll();
        let filterData = subData.filter(item => {
          return item.name === name && item.fatherId === parseInt(fatherId);
        });
        if (filterData.length === 0) {
          tempTypeTwo = subData;
        } else {
          throw this.ctx.helper.getErrorMsg(215);
        }

        // 添加子节点是，父id必须存在
        let result = await this.ctx.model.Category.findOne({
          where: {
            categoryId: parseInt(fatherId)
          }
        });

        if (!result) {
          throw this.ctx.helper.getErrorMsg(216);
        }
      }

      if (parseInt(type) === 1 && !name) {
        throw this.ctx.helper.getErrorMsg(207);
      }

      if (parseInt(type) === 1 && name) {
        // 判断写入是否重复
        let list = await this.ctx.model.Category.findAll();

        let typeList = list.filter(item => {
          return item.name === name;
        });
        if (typeList.length === 0) {
          tempTypeOne = list;
        } else {
          throw this.ctx.helper.getErrorMsg(215);
        }
      }

      switch (parseInt(type)) {
        case 1:
        default:
          let mapArray = tempTypeOne.map(item => {
            const categoryId = 'categoryId';
            return parseInt(item[categoryId]);
          });
          const maxCategoryId: any = Math.max.apply(Math, mapArray.length === 0 ? [0] : mapArray);
          await this.ctx.model.Category.create({
            name: name,
            categoryId: parseInt(maxCategoryId) + 1,
            type: 1,
            isShow: 1
          });
          break;
        case 2:
          let tempArray = tempTypeTwo.map(item => {
            const subCategoryId = 'subCategoryId';
            return parseInt(item[subCategoryId]);
          });
          const maxSubCategoryId: any = Math.max.apply(Math, tempArray.length === 0 ? [0] : tempArray);
          await this.ctx.model.SubCategory.create({
            name: name,
            type: 2,
            fatherId: parseInt(fatherId),
            subCategoryId: maxSubCategoryId + 1,
            isShow: 1
          });
      }

      this.ctx.response.body = {
        code: 200,
        status: '成功'
      }
    } catch (msg) {
      this.ctx.response.body = msg;
    }

  }

  /**
   * @api {post} category/update 修改分类
   *  
   * @apiName update
   * @apiGroup Category
   * @apiParam {String} type 分类类型[1-一级分类 2-二级分类]
   * @apiParam {String} id 分类id
   * @apiParam {String} name 修改后分类的名称
   * @apiParam {String} fatherId 父分类id
   * @apiParam {String} categoryType 分类类型
   * @apiHeaderExample {json} headers:
   *     {
   *       "token": "admin_token"
   *     }
   *
   */
  public async update() {
    try {
      let { type, id, name, fatherId } = this.ctx.request.body;
      if (
        !type ||
        (parseInt(type) !== 1 && parseInt(type) !== 2) ||
        !id ||
        !name) {
        throw this.ctx.helper.getErrorMsg(207);
      }
      switch (parseInt(type)) {
        case 2:
          await this.ctx.model.SubCategory.update({
            name: name,
            fatherId: parseInt(fatherId)
          },
            {
              where: {
                subCategoryId: parseInt(id)
              }
            });
          break;
        case 1:
        default:
          await this.ctx.model.Category.update({
            name: name,
          },
            {
              where: {
                categoryId: parseInt(id)
              }
            })
          break;
      }
      this.ctx.response.body = {
        code: 200,
        status: '成功'
      }

    } catch (msg) {
      this.ctx.response.body = msg;
    }
  }

  /**
   * @api {get} category/delete 删除分类
   *  
   * @apiName delete
   * @apiGroup Category
   * @apiParam {String} type 分类类型[1-一级分类 2-二级分类]
   * @apiParam {String} categoryId 父分类id
   * @apiParam {String} [subCategoryId] 子分类id
   * @apiHeaderExample {json} headers:
   *     {
   *       "token": "admin_token"
   *     }
   *
   */
  public async delete(ctx) {
    let { type, categoryId, subCategoryId } = ctx.request.query;
    try {
      if (
        !type || !categoryId ||
        (parseInt(type) !== 1 && parseInt(type) !== 2)) {
        throw this.ctx.helper.getErrorMsg(207);
      }
      // 一级分类
      if (parseInt(type) === 1 && categoryId && categoryId) {
        let count = await this.ctx.model.SubCategory.count({
          where: {
            fatherId: parseInt(categoryId),
          }
        });
        if (count !== 0) {
          throw this.ctx.helper.getErrorMsg(217);
        }
      }
      // 二级分类
      if (parseInt(type) === 2 && subCategoryId) {
        let count = await this.ctx.model.Article.count({
          where: {
            categoryId: parseInt(categoryId),
            subCategoryId: parseInt(subCategoryId)
          }
        });
        if (count > 0) {
          throw this.ctx.helper.getErrorMsg(218);
        }
      }
      switch (parseInt(type)) {
        case 1:
        default:
          await this.ctx.model.Category.destroy({
            where: {
              categoryId: parseInt(subCategoryId)
            }
          });
          break;
        case 2:
          await this.ctx.model.SubCategory.destroy({
            where: {
              subCategoryId: parseInt(subCategoryId)
            }
          });
          break;
      }

      ctx.response.body = {
        code: 200,
        status: '删除成功'
      }
    } catch (msg) {
      ctx.response.body = msg;
    }

  }
}
